home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 076-100 / scopedisk83 / popcli4 / cback.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  4KB  |  150 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\ Copyright (c) 1988 The Software Distillery.  All Rights Reserved */
  3. /* |. o.| || This program may not be distributed without the permission of   */
  4. /* | .  | || the authors.                                                    */
  5. /* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
  6. /* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
  7. /* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9.  
  10. /* C version of a new cback.a for PopCLI */
  11. /* This code should be put in the throwaway segment. It will clone the */
  12. /* second segment of this process into an independent seglist, and do  */
  13. /* a CreateProc for it.                                                */
  14.  
  15. #include <exec/types.h>
  16. #include <exec/alerts.h>
  17. #include <exec/nodes.h>
  18. #include <exec/lists.h>
  19. #include <exec/ports.h>
  20. #include <exec/libraries.h>
  21. #include <exec/tasks.h>
  22. #include <exec/memory.h>
  23. #include <libraries/dos.h>
  24. #include <libraries/dosextens.h>
  25. #include <workbench/startup.h>
  26. #include <string.h>
  27. #include <proto/exec.h>
  28. #include <proto/dos.h>
  29.  
  30. #include "cback.h"
  31.  
  32. /* Constants for the new process: */
  33. #define PROCNAME  "PopCLI IV"
  34. #define STACKSIZE 4096
  35. #define PRIORITY  20
  36.  
  37. struct Segment {
  38.     ULONG    sm_len;
  39.     BPTR    sm_next;
  40. };
  41.  
  42. /* Get a Task pointer from the MsgPort pointer returned by CreateProc */
  43. #define GETTASK(m)    (((struct Task *)m)-1)
  44.  
  45. void __far _main(void);
  46.  
  47. void __asm start(register __a0 char *cmd, register __d0 char *cmdlen)
  48. {
  49.     struct DosLibrary    *DOSBase;
  50.     struct Process        *us;
  51.     struct MemList        memlist, *ml;
  52.     struct Segment        *segment;
  53.     char            *newseg;
  54.     struct cbackstr        *msg;
  55.     BPTR            cwd;
  56.     int            sig;
  57.     struct MsgPort        *procmsg;
  58.     struct WBStartup    *wbmsg;
  59.     BPTR            stdin;
  60.  
  61.     DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
  62.     
  63.     us = (struct Process *)FindTask(0);
  64.  
  65.     msg = AllocMem( sizeof(struct cbackstr),
  66.                 MEMF_PUBLIC|MEMF_CLEAR );
  67.  
  68.     msg->msgpart.mn_Length = sizeof(struct cbackstr);
  69.  
  70.     cwd = us->pr_CurrentDir;
  71.     if (us->pr_CLI)
  72.     {
  73.         /* Run from CLI. We need to duplicate the lock for the    */
  74.         /* current working directory.                */
  75.         cwd = DupLock(cwd);
  76.         
  77.         /* Find the _main()'s segment. We need to clone it      */
  78.         /* KLUDGE WARNING: to find _main's segment, back up 8   */
  79.         /* bytes from the address of _main.                     */
  80.         segment = (struct Segment *)  (((char *)_main)-8);
  81.  
  82.         memlist.ml_NumEntries = 1;
  83.         memlist.ml_ME[0].me_Reqs = MEMF_PUBLIC;
  84.         memlist.ml_ME[0].me_Length = segment->sm_len;
  85.  
  86.         ml = AllocEntry( &memlist );
  87.         newseg = (char *) ml->ml_ME[0].me_Addr;
  88.  
  89.         memcpy( newseg, (char *)(&(segment->sm_next)),
  90.                 segment->sm_len );
  91.         *((long *)newseg) = 0;
  92.  
  93.         /* set up the message fields we now need */
  94.         msg->stdout = Open("*", MODE_OLDFILE);
  95.         msg->SyncProcess = us;
  96.         msg->SyncSignal = sig = AllocSignal(-1);
  97.         msg->cmd = cmd;
  98.         msg->cmdlen = cmdlen;
  99.  
  100.         /* Start up the new proc */
  101.         Forbid();
  102.         procmsg = CreateProc(
  103.                     PROCNAME,
  104.                     PRIORITY,
  105.                     (BPTR)((ULONG)newseg>>2),
  106.                     STACKSIZE
  107.                     );
  108.         if (procmsg)
  109.         {
  110.             AddTail( &(GETTASK(procmsg)->tc_MemEntry),
  111.                  (struct Node *)ml );
  112.         }
  113.         Permit();
  114.  
  115.         /* Let 'em go, but wait until they let us go */
  116.         if (procmsg && sig >= 0)
  117.         {
  118.             PutMsg( procmsg, (struct Message *)msg );
  119.             Wait(1<<sig);
  120.         }
  121.     }
  122.     else
  123.     {
  124.         /* We're a WorkBench process. Don't fork, but get the    */
  125.         /* workbench message and use stuff from it.        */
  126.         WaitPort( &us->pr_MsgPort );
  127.         wbmsg = (struct WBStartup *)GetMsg( &us->pr_MsgPort );
  128.         cwd = CurrentDir( wbmsg->sm_ArgList->wa_Lock );
  129.  
  130.         /* Stuff to get cmdline & stuff */
  131.  
  132.         stdin = Open( wbmsg->sm_ToolWindow, MODE_OLDFILE );
  133.  
  134.         /* Send ourselves the message, since we're going to be    */
  135.         /* waiting for it                    */
  136.         PutMsg( &us->pr_MsgPort, (struct Message *)msg );
  137.  
  138.         /* Call the main routine */
  139.         _main();
  140.         
  141.         Close(stdin);
  142.         /* Forbid();   is this really necessary???? */
  143.         ReplyMsg((struct Message *)wbmsg);
  144.     }
  145.  
  146.     UnLock(cwd);
  147.     CloseLibrary((struct Library *)DOSBase);
  148. }
  149.  
  150.